package problem;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Set;

import core.ObjectiveTarget;
import core.Result;

public class Markowitz extends PortfolioProblem {
	private double covariances[][];

	public Markowitz() {
		this.name = "Markowitz";
		this.restLowerBounds = 0;
		this.restUpperBounds = 1;
		this.firstLowerBounds = new double[0];
		this.firstUpperBounds = new double[0];
		this.objectiveTargets = new ObjectiveTarget[2];
		this.objectiveTargets[0] = ObjectiveTarget.MINIMIZE;
		this.objectiveTargets[1] = ObjectiveTarget.MAXIMIZE;

	}

	public void loadData(FileReader fr) throws IOException {
		//czyta plik w formacie
		// linia z nazwami papierow
		// linia z kursami z ostatniego dnia danych w arkuszu
		// linia z przewidywanymi zmianami kursu
		// trójkąt macierzy z kowariancjami
		
		BufferedReader br = new BufferedReader(fr);
		// linia z nazwami papierow
		String line = br.readLine();
		String [] betastr = line.split("\t");
		names = new String [betastr.length];
		int i = 0;
		try {
			while (true){
				names[i] = betastr[i];
				i++;
			}
		} catch (IndexOutOfBoundsException iex){
			//
		}
		
		
		// linia z kursami z ostatniego dnia danych w arkuszu
		if ((line = br.readLine()) == null){
			throw new IOException();
		}
		betastr = line.replace(',', '.').split("\t");
		value = new double [betastr.length];
		i = 0;
		try {
			while (true){
				value[i] = Double.parseDouble(betastr[i]);
				i++;
			}
		} catch (NumberFormatException  ex){
			//zle dane w pliku
			throw new IOException();
		} catch (IndexOutOfBoundsException iex){
			//
		}
		
		
		// linia z rzeczywistymi wartościami prognozowanych kursów
		if ((line = br.readLine()) == null){
			throw new IOException();
		}
		betastr = line.replace(',', '.').split("\t");
		realValues = new double [betastr.length];
		i = 0;
		try {
			while (true){
				realValues[i] = Double.parseDouble(betastr[i]);
				i++;
			}
		} catch (NumberFormatException  ex){
			//zle dane w pliku
			throw new IOException();
		} catch (IndexOutOfBoundsException iex){
			//
		}
		
		
		// linia z przewidywanymi zmianami kursu
		if ((line = br.readLine()) == null){
			throw new IOException();
		}
		String [] ratestr = line.replace(',', '.').split("\t");
		predictions = new double [ratestr.length];
		covariances = new double [ratestr.length][ratestr.length];
		i = 0;
		try {
			while (true){
				predictions[i] = Double.parseDouble(ratestr[i]);
				i++;
			}
		} catch (NumberFormatException  ex){
			//zle dane w pliku
			throw new IOException();
		} catch (IndexOutOfBoundsException iex){
			//
		}
		
		
		
		// trójkąt macierzy z kowariancjami
		for(int j=0;j<ratestr.length;j++) {
			if ((line = br.readLine()) == null){
				throw new IOException();
			}
			betastr = line.replace(',', '.').split("\t");
			i = 0;
			try {
				while (true){
					covariances[j][i] = Double.parseDouble(betastr[i]);
					covariances[i][j] = Double.parseDouble(betastr[i]);
					i++;
				}
			} catch (NumberFormatException  ex){
				//zle dane w pliku
				throw new IOException();
			} catch (IndexOutOfBoundsException iex){
				//
			}
		}


	}

	public int getProblemSize(){
		if (names != null)
			return names.length;
		return -1;
	}

	@Override
	public double[] calculate(double[] genotype) {
		double predicted_return_rate = 0.;
		double predicted_risk = 0.;
		try {
			int i=0;
			while(true) {
				predicted_return_rate+=genotype[i]*this.predictions[i];
				try {
					int j=0;
					while(true) {
						predicted_risk+=genotype[i]*genotype[j]*this.covariances[i][j];
						j++;
					}
				} catch(Exception e) {}
				i++;
			}
		}catch(Exception e) {}
		double[] result = new double[2];
		result[0] = predicted_risk;
		result[1] = predicted_return_rate;
		return result;
	}

	@Override
	public String getOptimalSolution() {
		return null;
	}

	@Override
	public double getHVR(Set<Result> results) {
		return 1;
	}
	

}
